package com.leesche.zcsp.node.web.controller.web.user;

import com.leesche.zcsp.node.utils.web.PagingResult;
import com.leesche.zcsp.node.utils.web.messge.WebResult;
import com.leesche.zcsp.node.web.constants.Constants;
import com.leesche.zcsp.node.web.controller.template.UserTemplate;
import com.leesche.zcsp.node.web.model.SysModule;
import com.leesche.zcsp.node.web.model.SysRoleModuleCriteria;
import com.leesche.zcsp.node.web.service.SysRoleModuleService;
import com.leesche.zcsp.node.web.service.impl.data.read.QuerySysModuleCondition;
import com.leesche.zcsp.node.web.service.impl.data.read.SysModuleDto;
import com.leesche.zcsp.node.web.vo.Module;
import com.leesche.zcsp.node.web.vo.Privilege;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpSession;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @author 陈立勇
 * @version V1.0
 * @Title: ModuleController.java
 * @Description: TODO(系统权限控制器)
 * @date 2016年9月26日 下午8:06:07
 */
@Controller
@RequestMapping("/web/module")
public class ModuleController extends UserTemplate {

    private final static Logger LOGGER = Logger.getLogger(ModuleController.class.getName());

    private static final String LIST_VIEW = "web/module/modules";
    private static final String ADD_VIEW = "web/module/addView";
    private static final String EDIT_VIEW = "web/module/editView";

    @Autowired
    private SysRoleModuleService sysRoleModuleService;

    /**
     * @return 权限列表视图路径
     * @Title: showListView
     * @Description: TODO(显示权限列表视图)
     * @author 陈立勇
     */
    @RequestMapping(value = "/modulelist", method = RequestMethod.GET)
    public String showListView() {
        return LIST_VIEW;
    }

    /**
     * @return 新增权限视图路径
     * @Title: showAddView
     * @Description: TODO(显示新增权限视图)
     * @author 陈立勇
     */
    @RequestMapping(value = "/moduleAddView", method = RequestMethod.GET)
    public String showAddView(final Model model) {

        List<Module> parentModules = getCacheModules();

        model.addAttribute("parentModuleList", parentModules);

        return ADD_VIEW;

    }

    /**
     * @param id 需编辑的权限ID
     * @return 编辑框视图 路径
     * @Title: showEditView
     * @Description: TODO(显示包含权限信息的编辑框视图)
     * @author 陈立勇
     */
    @RequestMapping(value = "/{id}/moduleEditView", method = RequestMethod.GET)
    public String showEditView(final @PathVariable("id") Long id,
                               final Model model) {

        List<Module> parentModules = getCacheModules();
        model.addAttribute("parentModuleList", parentModules);

        SysModule sysModule = sysModuleService.selectByPrimaryKey(id);
        model.addAttribute("module", sysModule);

        return EDIT_VIEW;
    }

    /**
     * @param condition 分页条件
     * @return 响应报文
     * @Title: listJson
     * @Description: TODO(获取权限列表)
     * @author 陈立勇
     */
    @ResponseBody
    @RequestMapping(value = "/list.json", method = RequestMethod.GET, produces = "application/json;charset=UTF-8")
    public Map<String, Object> listJson(final QuerySysModuleCondition condition) {

        PagingResult<SysModuleDto> pagingResult = sysModuleService
                .findAllByPage(condition);

        Map<String, Object> json = WebResult.buildOf(pagingResult).toMap();

        return json;
    }

    /**
     * @param module 相应报文
     * @Title: addModule
     * @Description: TODO(新增系统权限)
     * @author 陈立勇
     */
    @ResponseBody
    @RequestMapping(value = "/newModule", method = RequestMethod.POST)
    public Map<String, Object> addModule(final SysModule module,
                                         HttpSession session) {
        try {
            // 获取当前登录的用户
            module.setAdminid(privilegeService.getCurrentPrincipal().getUserid());
            module.setUpdatetime(new Date());

            int result = sysModuleService.insertSelective(module);

            if (result > 0) {
                SysModuleDto sysModuleDto = new SysModuleDto(module.getModuleid(), module.getPmoduleid(), module.getSname(), module.getNamecn(), module.getAttribute(), module.getNtype(), module.getUrl(), module.getRemark(), module.getAdminid().toString(), module.getUpdatetime());
                
                //同步内存
                if (module.getNtype() == Constants.MODULE_TYPE_WEB) {
                    privilegeService.addWebPrivilege(sysModuleDto);
                } else if (module.getNtype() == Constants.MODULE_TYPE_WECHAT) {
                    privilegeService.addWechatPrivilege(sysModuleDto);
                } else if (module.getNtype() == Constants.MODULE_TYPE_APP) {
                    privilegeService.addAppPrivilege(sysModuleDto);
                } else if (module.getNtype() == Constants.MODULE_TYPE_OPERATION) {
                    privilegeService.addOperationPrivilege(sysModuleDto);
                }

            }

            return WebResult.success().info("操作成功！").toMap();

        } catch (Exception e) {
            LOGGER.error(e, e);
            return WebResult.failure(e).toMap();
        }

    }

    /**
     * @param module 相应报文
     * @Title: editModule
     * @Description: TODO(编辑系统权限)
     * @author 陈立勇
     */
    @ResponseBody
    @RequestMapping(value = "/eidtModule", method = RequestMethod.POST)
    public Map<String, Object> editModule(final SysModule module) {
        try {

            module.setAdminid(privilegeService.getCurrentPrincipal().getUserid());
            module.setUpdatetime(new Date());
            int result = sysModuleService.updateByPrimaryKeySelective(module);

            if (result > 0) {
                SysModuleDto sysModuleDto = new SysModuleDto(module.getModuleid(), module.getPmoduleid(), module.getSname(), module.getNamecn(), module.getAttribute(), module.getNtype(), module.getUrl(), module.getRemark(), module.getAdminid().toString(), module.getUpdatetime());

                //同步内存
                if (module.getNtype() == Constants.MODULE_TYPE_WEB) {
                    privilegeService.updateWebPrivilege(sysModuleDto);
                } else if (module.getNtype() == Constants.MODULE_TYPE_WECHAT) {
                    privilegeService.updateWechatPrivilege(sysModuleDto);
                } else if (module.getNtype() == Constants.MODULE_TYPE_APP) {
                    privilegeService.updateAppPrivilege(sysModuleDto);
                } else if (module.getNtype() == Constants.MODULE_TYPE_OPERATION) {
                    privilegeService.updateOperationPrivilege(sysModuleDto);
                }
            }

            return WebResult.success().info("操作成功！").toMap();
        } catch (Exception e) {
            LOGGER.error(e, e);
            return WebResult.failure(e).toMap();
        }

    }

    /**
     * @param id 需删除的权限ID
     * @Title: delModule
     * @Description: TODO(移除系统权限)
     * @author 陈立勇
     */
    @ResponseBody
    @RequestMapping(value = "/{id}/removeModule", method = RequestMethod.DELETE)
    public Map<String, Object> delModule(final @PathVariable("id") long id) {
        try {
            //删除角色权限
            SysRoleModuleCriteria criteria = new SysRoleModuleCriteria();
            criteria.or().andModuleidEqualTo(id);
            sysRoleModuleService.deleteByCriteria(criteria);
            //删除权限
            int result = sysModuleService.deleteByPrimaryKey(id);

            if (result > 0) {
            	//同步内存
                privilegeService.deleteAppPrivilege(id);
                privilegeService.deleteOperationPrivilege(id);
                privilegeService.deleteWebPrivilege(id);
                privilegeService.deleteWechatPrivilege(id);
            }

            return WebResult.success().info("操作成功！").toMap();
        } catch (Exception e) {
            LOGGER.error(e, e);
            return WebResult.failure(e).toMap();
        }
    }


    private List<Module> getCacheModules() {
        List<Module> parentModules = new ArrayList<Module>();

        Map<Long, Privilege> WebModules = privilegeService.getWebPrivileges();
        Module webModule = appendParentModule(WebModules, Constants.MODULE_TYPE_WEB);

        if (webModule != null) {
            parentModules.add(webModule);
        }

        Map<Long, Privilege> wechatModules = privilegeService.getWechatPrivileges();
        Module wechatModule = appendParentModule(wechatModules, Constants.MODULE_TYPE_WECHAT);
        if (wechatModule != null) {
            parentModules.add(wechatModule);
        }

        Map<Long, Privilege> appModules = privilegeService.getAppPrivileges();
        Module appModule = appendParentModule(appModules, Constants.MODULE_TYPE_APP);
        if (appModule != null) {
            parentModules.add(appModule);
        }
        return parentModules;
    }


    private Module appendParentModule(Map<Long, Privilege> modules, Integer moduleType) {
        Module parnetModule = null;

        for (Map.Entry<Long, Privilege> entry : modules.entrySet()) {
            Long moduleid = entry.getKey();
            Long parentid = entry.getValue().getParentID();
            if (moduleid.equals(parentid)) {
                parnetModule = new Module(moduleid, parentid, entry.getValue().getModuleName(), moduleType);
                parnetModule.setChildModules(this.appendChildModules(parnetModule, modules));
            }

        }
        return parnetModule;
    }

    private List<Module> appendChildModules(Module parentModule, Map<Long, Privilege> modules) {

        List<Module> ChildModules = new ArrayList<Module>();
        for (Map.Entry<Long, Privilege> entry : modules.entrySet()) {

            Long moduleid = entry.getKey();
            Long parentid = entry.getValue().getParentID();

            if (!moduleid.equals(parentid) && parentModule.getModuleid().equals(parentid)) {
                Module childModule = new Module(moduleid, parentid, entry.getValue().getModuleName(), parentModule.getModuleScope());
                childModule.setChildModules(this.appendChildModules(childModule, modules));
                ChildModules.add(childModule);
            }

        }

        return ChildModules;
    }

}
